import json
import socket
import threading
from xmlrpc.server import SimpleXMLRPCServer

from flask import Flask
from gevent import pywsgi
from geventwebsocket.handler import WebSocketHandler

#self.ws.handler.server.clients获取到全部连接dict(key=addr,value=class包含ws)

from geventwebsocket import WebSocketServer, WebSocketApplication, Resource
from collections import OrderedDict

class Config:
    def __init__(self):
        self.rooms = {} # key: room number value: client_array
        self.members = {} #key: addr_tuple value:room number



CONFIG = Config()

class EchoApplication(WebSocketApplication):
    #init 每个ws 连接 进来 都会走
    def __init__(self, ws):
        super().__init__(ws)

    def addroom(self):
        path_arr = self.ws.path.split("/")# ws://localhost:5555/index/roomnumber
        room_number = path_arr[len(path_arr)-1-1]
        if room_number and room_number not in CONFIG.rooms:
            CONFIG.rooms[room_number] = [] #新建房间
        CONFIG.rooms[room_number].append(self.ws.handler.active_client)
        CONFIG.members[self.ws.handler.active_client.address] = room_number

    def on_open(self):
        self.addroom()
        print("Connection opened")

    def getRoomNumByAddr(self):
        return CONFIG.members[self.ws.handler.active_client.address] #获取房间号

    def on_message(self, message):
        if message == None or message == "":
            return
        message_obj = json.loads(message.decode("utf-8")) #get bytes from js page.orignal bytes tranfer to str.str transfer to dict.
        nickname = message_obj["nickname"]
        mes_type = message_obj["type"]
        content = message_obj["content"]
        roomNum = self.getRoomNumByAddr()
        for client in CONFIG.rooms[roomNum]:
            if client and client.ws and message:
                client.ws.send(
                    json.dumps({
                        "msg_type":mes_type,
                        "nickname":nickname,
                        "content":content
                    })
                )

    def on_close(self, reason):
        roomNum = self.getRoomNumByAddr()#移除我们的房间和人员
        CONFIG.members.pop(self.ws.handler.active_client.address)
        CONFIG.rooms[roomNum].remove(self.ws.handler.active_client)

        if len(CONFIG.rooms[roomNum]) <= 0:
            CONFIG.rooms.pop(roomNum)
        print("client exit!")

# flask_app = Flask(__name__)
#
# #获取指定房间的人数
# @flask_app.route("/personcount/<roomnum>")
# def personcount(roomnum):
#     result = {"roomnum":roomnum, "count":0}
#     if roomnum not in CONFIG.rooms.keys():
#         pass
#     else:
#         if (count := len(CONFIG.rooms[roomnum])) > 0:
#             result["count"] = count
#         else:
#             pass
#     print(json.dumps(result))
#     return result
#
# def routeapp():
#     flask_app.run(host="0.0.0.0", port=8887)

def personcount(roomnum):
    result = {"roomnum":roomnum, "count":0}
    if roomnum not in CONFIG.rooms.keys():
        pass
    else:
        if (count := len(CONFIG.rooms[roomnum])) > 0:
            result["count"] = count
        else:
            pass
    print(json.dumps(result))
    return result

def rpcserver():
    server = SimpleXMLRPCServer(("0.0.0.0",8848))
    server.register_function(personcount)
    server.serve_forever()

if __name__ == "__main__":
    threading.Thread(target=rpcserver, args=()).start()
    WebSocketServer(
        ('0.0.0.0', 5555),
        Resource(OrderedDict([('/echo/*', EchoApplication)]))
    ).serve_forever()


# web server gateway interface impl
# def websocket_app(environ, start_response):
#     if environ["PATH_INFO"] == '/echo':
#         ws = environ["wsgi.websocket"]
#         while 1:
#             message = ws.receive()
#             result = {}
#             result["message"] = message.decode("utf-8")
#             # send json  string
#             ws.send(json.dumps(result))
#
# server = pywsgi.WSGIServer(("0.0.0.0", 5555), websocket_app,
#     handler_class=WebSocketHandler) # init server
# server.serve_forever() # start server
